package org.example.hypersonaltools.scene;

import javafx.animation.Animation;
import javafx.animation.ParallelTransition;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.util.Duration;
import org.example.hypersonaltools.dllFile.DLLLibrary;
import org.example.hypersonaltools.sqlite.SqliteExample;
import org.example.hypersonaltools.sqlite.TestTableSqlImpl;

import java.awt.Desktop;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ToolScene implements FXScene {
    private Scene scene;
    private Pane root;
    private DLLLibrary dllLibrary;
    private SqliteExample testDB;
    private static Boolean stopped = false;
    private final List<ParallelTransition> parallelTransitions = new ArrayList<>();

    public ToolScene() {
        root = new Pane();
        scene = new Scene(root, 800, 600);
        testDB = new SqliteExample("test");
        setupDragAndDrop();
        dllLibrary = DLLLibrary.getInstance();
    }

    private void setupDragAndDrop() {

        root.setOnDragOver(event -> {
            if (event.getDragboard().hasFiles()) {
                event.acceptTransferModes(TransferMode.COPY);
            }
            event.consume();
        });

        root.setOnDragDropped(event -> {
            Dragboard db = event.getDragboard();
            boolean success = false;
            if (db.hasFiles()) {
                List<File> files = db.getFiles();
                for (File file : files) {
                    addShortcutIcon(file);
                    success = true;
                }
            }
            event.setDropCompleted(success);
            event.consume();
        });
        TestTableSqlImpl testTable = new TestTableSqlImpl(testDB.connection);
        List<TestTableSqlImpl.iconData> query = testTable.query();
        if (query!=null&&!query.isEmpty()) {
            creatAnimate(query);
        }
        root.setOnMousePressed(mouseEvent -> {
            if (mouseEvent.getClickCount() == 2&&!stopped) {
                parallelTransitions.forEach(Animation::pause);
                stopped = true;
            }else if (mouseEvent.getClickCount() == 2&&stopped){
                parallelTransitions.forEach(Animation::play);
                stopped = false;
            }
        });
    }

    private void creatAnimate(List<TestTableSqlImpl.iconData> query) {
        int numTags = query.size();
        double radius = 300;

        List<Double[]> zbs = new ArrayList<>();
        for (int i = 0; i < numTags; i++) {
            double phi = Math.acos(1 - (double) (2 * (i + 0.5)) / numTags); // 极角
            double theta = Math.PI * (1 + Math.sqrt(5)) * i; // 方位角
            double z = radius * Math.cos(phi); // z 坐标（可用于深度调整）
            zbs.add(new Double[]{radius*Math.sin(phi)*Math.cos(theta), radius*Math.sin(phi)*Math.sin(theta),z});
        }

        int maxIterations = 1000; // 最大迭代次数
        double stepSize = 0.01; // 步长
        List<Double[]> optimizedPoints = OneToolScene.electrostaticRepulsion(zbs, radius, maxIterations, stepSize);

        for (int i = 0; i < optimizedPoints.size(); i++) {
            TestTableSqlImpl.iconData iconData = query.get(i);
            File file = new File(iconData.getPath());
            VBox vBox = creatVBox(iconData.getIconImageData(), file);
            vBox.setOpacity(1);
            root.getChildren().add(vBox);

            Double[] coordinates = optimizedPoints.get(i);
            if (coordinates[0]>0){
//                System.out.println(file.getName()+coordinates[0]);
                vBox.setLayoutX(400);
            }else {
                vBox.setLayoutX(400);
//                System.out.println(file.getName()+"小于"+coordinates[0]);
            }
            vBox.setLayoutY(300 + coordinates[1]);
            // 调用封装方法
            parallelTransitions.add(OneToolScene.createOrbitalAnimation(vBox, coordinates, 200, 20, Duration.seconds(5), 100));
        }
    }

    private void addShortcutIcon(File shortcutFile) {
        //初始化com库
        String pathToIcon = "";
        byte[] iconData = dllLibrary.getPathToIcon(shortcutFile);
        VBox vBox = creatVBox(iconData, shortcutFile);
        root.getChildren().add(vBox);

        TestTableSqlImpl testTable = new TestTableSqlImpl(testDB.connection);
        testTable.add(shortcutFile.getPath(),iconData);
    }

    private VBox creatVBox(byte[] iconData,File shortcutFile) {
        //将iconData前八个字节取出，前八个字节分成前四为宽度后四为高度,后面的是位图数据
        byte[] widthAndHeight = Arrays.copyOf(iconData, 8);
        byte[] icondata = Arrays.copyOfRange(iconData, 8, iconData.length);
        ByteBuffer pixelBuffer = ByteBuffer.wrap(icondata);
        pixelBuffer.order(ByteOrder.LITTLE_ENDIAN); // 设置字节顺序为小端序
        ByteBuffer buffer = ByteBuffer.wrap(widthAndHeight);
        buffer.order(ByteOrder.LITTLE_ENDIAN);
        // 读取前4个字节作为宽度
        int width = buffer.getInt();
        // 读取后4个字节作为高度
        int height = buffer.getInt();

        Image image = null;
        try {
            BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            // 将位图数据复制到 BufferedImage 中
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    int index = (y * width + x) * 4; // 假设每个像素占 4 个字节 (ARGB)
                    int b = pixelBuffer.get() & 0xFF; // Blue
                    int g = pixelBuffer.get() & 0xFF; // Green
                    int r = pixelBuffer.get() & 0xFF; // Red
                    int a = pixelBuffer.get() & 0xFF; // Alpha
                    int pixel = (a << 24) | (r << 16) | (g << 8) | b;
                    bufferedImage.setRGB(x, y, pixel);
                }
            }
            // 将 BufferedImage 转换为 JavaFX 的 Image
            image = SwingFXUtils.toFXImage(bufferedImage, null);
        } catch (Exception e) {
            e.printStackTrace();
        }

        ImageView imageView = new ImageView(image);
        imageView.setFitWidth(width);
        imageView.setFitHeight(height);
        imageView.setX(50);
        imageView.setY(50);

        imageView.setOnMouseClicked(event -> {
            try {
                Desktop.getDesktop().open(shortcutFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        VBox vbox = new VBox();
        vbox.getChildren().addAll(imageView, new Label(shortcutFile.getName()));
        vbox.setAlignment(Pos.CENTER);
        return vbox;
    }


    @Override
    public Scene getScene() {
        return scene;
    }

    @Override
    public void onEnter() {

    }

    @Override
    public void onExit() {

    }
}
